
using System;
using System.Data;
using System.Linq;
using System.Linq.Dynamic;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;

using Abp.UI;
using Abp.AutoMapper;
using Abp.Extensions;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.Application.Services.Dto;
using Abp.Linq.Extensions;


using Yozeev.SystemConfig;
using Yozeev.SystemConfig.Dtos;
using Yozeev.SystemConfig.DomainService;
using Yozeev.SystemConfig.Authorization;
using Abp.Authorization.Users;
using Yozeev.Common;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Mvc;

namespace Yozeev.SystemConfig
{
	/// <summary>
	/// Menu应用层服务的接口实现方法  
	///</summary>
	[AbpAuthorize]
	public class MenuAppService : YozeevAppServiceBase, IMenuAppService
	{
		private readonly IRepository<Menu, Guid> _entityRepository;

		private readonly IMenuManager _entityManager;

		private readonly IRepository<Power, Guid> _powerRepository;

		private readonly IRepository<PowerRole, Guid> _powerRoleRepository;

		private readonly IRepository<UserRole, long> _userRoleRepository;

        private readonly IQueryHelper _queryHelper;

        /// <summary>
        /// 构造函数 
        ///</summary>
        public MenuAppService(
		IRepository<Menu, Guid> entityRepository
		, IMenuManager entityManager
		, IRepository<Power, Guid> powerRepository
		, IRepository<PowerRole, Guid> powerRoleRepository
		, IRepository<UserRole, long> userRoleRepository
        , IQueryHelper queryHelper
        )
		{
			_entityRepository = entityRepository;
			_entityManager = entityManager;
			_powerRepository = powerRepository;
			_powerRoleRepository = powerRoleRepository;
			_userRoleRepository = userRoleRepository;
            _queryHelper = queryHelper;
        }


		/// <summary>
		/// 获取Menu的分页列表信息
		///</summary>
		/// <param name="input"></param>
		/// <returns></returns>
		[HttpPost]
		public async Task<PagedResultDto<MenuListDto>> GetPaged(GetMenusInput input)
		{
			var expression = _queryHelper.WhereExp<Menu>(input.queryData);
			var query = _entityRepository.GetAll().Where(expression);
            // TODO:根据传入的参数添加过滤条件
            List<Menu> list = new List<Menu>();
            var queryList = query.OrderBy(m => m.Sort).ToList();
			if (queryList != null && queryList.Count > 0)
			{
				var parentList = queryList.Where(m => m.ParentId == null).OrderBy(m => m.Sort).ToList();
				parentList.ForEach(t => {
					list.Add(t);
					CreateSubMenuListDtoNode(queryList, t, list);
					queryList.Remove(t);
				});
			}
			if(queryList != null && queryList.Count > 0)
			{
				list.AddRange(queryList);
			}
            query = list.AsQueryable();
            //var count = await query.CountAsync();
            var count = query.Count();

            var entityList = query
					//.OrderBy(input.Sorting)
                    .AsNoTracking()
					.PageBy(input)
					.ToList();

            var entityListDtos = ObjectMapper.Map<List<MenuListDto>>(entityList);
            return new PagedResultDto<MenuListDto>(count, entityListDtos);
        }

        /// <summary>
        /// 获取Menu的分页列表信息--Get方法
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<MenuListDto>> GetPagedForGet(GetMenusInputForGet input)
        {
            List<QueryData> queryDatas = JsonConvert.DeserializeObject<List<QueryData>>(input.queryData);
            var query = _entityRepository.GetAll().Where(_queryHelper.WhereExp<Menu>(queryDatas));
            // TODO:根据传入的参数添加过滤条件
            List<Menu> list = new List<Menu>();
            var queryList = query.ToList();
            if (queryList != null && queryList.Count > 0)
                queryList.Where(m => m.ParentId == null).OrderBy(m => m.Sort).ToList().ForEach(t => {
                    list.Add(t);
                    CreateSubMenuListDtoNode(queryList, t, list);
                });
            query = list.AsQueryable();
            //var count = await query.CountAsync();
            var count = query.Count();

            var entityList = query
                    //.OrderBy(input.Sorting)
                    .AsNoTracking()
                    .PageBy(input)
                    .ToList();

            // var entityListDtos = ObjectMapper.Map<List<DeviceListDto>>(entityList);
            var entityListDtos = entityList.MapTo<List<MenuListDto>>();

            return new PagedResultDto<MenuListDto>(count, entityListDtos);
        }
        private void CreateSubMenuListDtoNode(List<Menu> items, Menu item, List<Menu> menuTrees)
        {
            List<Menu> sub = items.Where(m => m.ParentId == item.Id).OrderBy(m => m.Sort).ToList();
            if (sub != null && sub.Count > 0)
                sub.ForEach(t => {
                    menuTrees.Add(t);
                    CreateSubMenuListDtoNode(items, t, menuTrees);
					items.Remove(t);
                });

        }

        /// <summary>
        /// 通过指定id获取MenuListDto信息
        /// </summary>
		public async Task<MenuListDto> GetById(EntityDto<Guid> input)
		{
			var entity = await _entityRepository.GetAsync(input.Id);

			return entity.MapTo<MenuListDto>();
		}

		/// <summary>
		/// 获取编辑 Menu
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task<GetMenuForEditOutput> GetForEdit(NullableIdDto<Guid> input)
		{
			var output = new GetMenuForEditOutput();
			MenuEditDto editDto;

			if (input.Id.HasValue)
			{
				var entity = await _entityRepository.GetAsync(input.Id.Value);

				editDto = entity.MapTo<MenuEditDto>();

				//menuEditDto = ObjectMapper.Map<List<menuEditDto>>(entity);
			}
			else
			{
				editDto = new MenuEditDto();
			}

			output.Menu = editDto;
			return output;
		}


		/// <summary>
		/// 添加或者修改Menu的公共方法
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task CreateOrUpdate(CreateOrUpdateMenuInput input)
		{

			if (input.Menu.Id.HasValue)
			{
				await Update(input.Menu);
			}
			else
			{
				await Create(input.Menu);
			}
		}


		/// <summary>
		/// 新增Menu
		/// </summary>
		protected virtual async Task<MenuEditDto> Create(MenuEditDto input)
		{
			//TODO:新增前的逻辑判断，是否允许新增

			// var entity = ObjectMapper.Map <Menu>(input);
			var entity = input.MapTo<Menu>();


			entity = await _entityRepository.InsertAsync(entity);
			return entity.MapTo<MenuEditDto>();
		}

		/// <summary>
		/// 编辑Menu
		/// </summary>
		protected virtual async Task Update(MenuEditDto input)
		{
			//TODO:更新前的逻辑判断，是否允许更新

			var entity = await _entityRepository.GetAsync(input.Id.Value);
			input.MapTo(entity);

			// ObjectMapper.Map(input, entity);
			await _entityRepository.UpdateAsync(entity);
		}



		/// <summary>
		/// 删除Menu信息的方法
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task Delete(EntityDto<Guid> input)
		{
			//TODO:删除前的逻辑判断，是否允许删除
			await _entityRepository.DeleteAsync(input.Id);
		}



		/// <summary>
		/// 批量删除Menu的方法
		/// </summary>
		public async Task BatchDelete(List<Guid> input)
		{
			// TODO:批量删除前的逻辑判断，是否允许删除
			await _entityRepository.DeleteAsync(s => input.Contains(s.Id));
		}
        #region 获取菜单树列表
        /// <summary>
        /// 查询菜单树
        /// </summary>
        /// <returns></returns>
        public async Task<List<MenuTreeDto>> GetMenuTree()
		{
			List<Menu> entityList = await GetMenusByUser();
			List<MenuTreeDto> menuTrees = new List<MenuTreeDto>();
			//查询无父Id的菜单项
			if (entityList != null && entityList.Count > 0)
				entityList.Where(m => m.ParentId == null).ToList().ForEach(t => {
					menuTrees.Add(GetMenuTreeDto(t));
					CreateSubMenuNode(entityList, t, menuTrees.Last());
				});
			return menuTrees;
		}
		private async Task<List<Menu>> GetMenusByUser()
		{
			//查询权限中拥有菜单
			
			var ownmenuList = new List<Guid>();
			//根据用户，查询菜单
			var query = _entityRepository.GetAll().Where(GetMenuExpressionByUser());
			// TODO:根据传入的参数添加过滤条件
			List<Menu> entityList = new List<Menu>();
			//if (this.GetCurrentUser().UserName != "Admin")
			{
				entityList = await query
					.OrderBy(m => m.Sort).AsNoTracking()
					.Where(m => m.IsEnabled)
					.ToListAsync();
			}
			//else
			//{
			//	//查询用户对应的角色Id
			//	var RoleId = this._userRoleRepository.GetAllIncluding(m => m.UserId == this.GetCurrentUser().Id).FirstOrDefault().Id;
			//	//查询用户的权限Id数组
			//	var powerRoles = this._powerRoleRepository.GetAllIncluding(m => m.RoleId == RoleId).Select(m => m.PowerId).ToArray();
			//	//查询用户的菜单Id数组
			//	var powers = this._powerRepository.GetAllIncluding(m => powerRoles.Contains(m.Id)).Select(m => m.MenuId).ToArray();
			//	//
			//	entityList = await query
			//						.OrderBy(m => m.Sort).AsNoTracking()
			//						.Where(m => m.IsEnabled && powers.Contains(m.Id))
			//						.ToListAsync();
			//	//var test = from menu in _entityRepository.GetAll()
			//	//			 where menu.IsEnabled && menu.Powers.Where(power=>power.PowerRoles.LongCount(powerRole=>powerRole.RoleId==RoleId)>0).LongCount()>0 
			//	//			 select menu
			//	//			 ;
			//	;
			//}
			return entityList;
		}
		private void CreateSubMenuNode(List<Menu> items, Menu item, MenuTreeDto menuTrees)
		{
			List<Menu> sub = items.Where(m => m.ParentId == item.Id).ToList();
			if(sub!=null&& sub.Count>0)
				sub.ForEach(t => {
					if(menuTrees.Childrens==null)
						menuTrees.Childrens = new List<MenuTreeDto>();
					menuTrees.Childrens.Add(GetMenuTreeDto(t));
					CreateSubMenuNode(items, t, menuTrees.Childrens.Last());
				});

		}
		private MenuTreeDto GetMenuTreeDto(Menu menu)
		{
			var menuTreeDto = new MenuTreeDto()
			{
				id = menu.Id.ToString(),
				i18n = menu.MenuCode,
				text = menu.MenuName,
				acl = "",
				link = menu.NavigateUrl,
				icon = menu.IocClassName
			};
			if (AbpUserBase.AdminUserName == GetCurrentUser().UserName)
			{
				menuTreeDto.IsAllOperation = true;
				menuTreeDto.OperationNames = new List<string>();
			}
			else
			{
				menuTreeDto.IsAllOperation = false;
				menuTreeDto.OperationNames = GetPowerCodeByUser(menu.Id);
			}
			return menuTreeDto;
		}
		#endregion
		#region 获取菜单的下拉树结构
		/// <summary>
		/// 查询菜单下拉树
		/// </summary>
		/// <returns></returns>
		public async Task<List<MenuDropDownDto>> GetMenuDropDown()
		{
			List<Menu> entityList = await GetMenusByUser();
			List<MenuDropDownDto> menuTreesList = new List<MenuDropDownDto>();
			//查询无父Id的菜单项
			if (entityList != null && entityList.Count > 0)
				entityList.Where(m => m.ParentId == null).ToList().ForEach(t => {
					menuTreesList.Add(new MenuDropDownDto(t.Id.ToString(), t.MenuName,true));
					CreateSubMenuDropDownNode(entityList, t, menuTreesList.Last());
				});
			return menuTreesList;
		}
		private void CreateSubMenuDropDownNode(List<Menu> items, Menu item, MenuDropDownDto menuTree)
		{
			List<Menu> sub = items.Where(m => m.ParentId == item.Id).ToList();
			if (sub != null && sub.Count > 0)
			{
				menuTree.isLeaf = false;
				sub.ForEach(t => {
					if (menuTree.children == null)
						menuTree.children = new List<MenuDropDownDto>();
					menuTree.children.Add(new MenuDropDownDto(t.Id.ToString(), t.MenuName, true));
					CreateSubMenuDropDownNode(items, t, menuTree.children.Last());
				});
			}
		}
		#endregion
		/// <summary>
		/// 导出Menu为excel表,等待开发。
		/// </summary>
		/// <returns></returns>
		//public async Task<FileDto> GetToExcel()
		//{
		//	var users = await UserManager.Users.ToListAsync();
		//	var userListDtos = ObjectMapper.Map<List<UserListDto>>(users);
		//	await FillRoleNames(userListDtos);
		//	return _userListExcelExporter.ExportToFile(userListDtos);
		//}

	}
}


